package com.suning.sawp.service.impl.job;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.suning.sawp.cache.RedisClient;
import com.suning.sawp.constants.CacheKeyConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.intf.model.BrandBean;
import com.suning.sawp.intf.model.ModelConstant;
import com.suning.sawp.intf.model.ModelManageDaoService;
import com.suning.sawp.intf.model.ModelTaskStoreBean;
import com.suning.sawp.intf.model.TaskInfoPart;
import com.suning.sawp.po.model.ModelTaskMain;
import com.suning.sawp.service.impl.bi.BIModelService;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.SCMConfigUtil;

public class ModelJobServiceImpl {

    @Resource
    BIModelService              biModelService;

    @Resource
    ModelManageDaoService       modelManageDaoService;

    @Autowired
    RedisClient                 redisClient;

    private static final String DATE_FORMAT              = "yyyy-MM-dd";

    private static final String DATE_FORMAT_YYYYMMDD     = "yyyyMMdd";

    private static final String UPLOAD_MODEL_LIST        = "uploadModelList";

    private static final String UPLOAD_MODEL_CLUSTER     = "uploadModelCluster";

    private static final String UPLOAD_MODEL_FINANCE     = "uploadModelFinance";

    private static final String DOWNLOAD_MODEL_NOCLUSTER = "downloadModelNoCluster";

    private static final String DOWNLOAD_SALE_MODEL_EXPT = "downloadSaleModelExpt";

    private static final String DOWNLOAD_MODEL_VALIDITY  = "downloadModelValidity";

    private static final String ASSIGN_TASK              = "assignTask";

    private static final String DOWNLOAD_SALE_MODEL      = "downloadSaleModel";

    private static final String EXCUTE_FLAG              = "1";
    
    /**
     * 财务样机增量路径
     */
    @Value("#{settingConfig[ftp_modelFinance_path]}")
    String FTP_MODEL_FINANCE_PATH;
    /**
     * 财务样机初始化路径
     */
    @Value("#{settingConfig[ftp_modelFinanceInit_path]}")
    String FTP_MODEL_FINANCE_INIT_PATH;

    /**
     * 
     * 功能描述: 上传样机清单job<br>
     * 〈功能详细描述〉
     * 
     * @throws SQLException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void uploadModelList(String date, Integer limit) throws SQLException {
        if (isExcute(UPLOAD_MODEL_LIST)) {
            try {
                biModelService.uploadModelList("/", date, "dj_model_main_list.dat", limit);
            } catch (Exception e) {
                throw new SQLException(e);
            } finally {
                cleanFlag(UPLOAD_MODEL_LIST);
            }
        }
    }

    private boolean isExcute(String type) {
        if (StringUtils.isNotBlank(type)
                && redisClient.hget(CacheKeyConstants.MODEL_JOB_EXCUTE_FLAG, type) == null) {
            redisClient.hset(CacheKeyConstants.MODEL_JOB_EXCUTE_FLAG, type, EXCUTE_FLAG);
            redisClient.expire(CacheKeyConstants.MODEL_JOB_EXCUTE_FLAG,
                    CacheKeyConstants.EXPIRE_TIME_ONE_DAY);
            return true;
        }
        return false;
    }

    private void cleanFlag(String type) {
        redisClient.hdel(CacheKeyConstants.MODEL_JOB_EXCUTE_FLAG, type);
    }

    /**
     * 
     * 功能描述: 上传商品簇列表job<br>
     * 〈功能详细描述〉
     * 
     * @throws SQLException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void uploadModelCluster(String date, Integer limit) throws SQLException {
        if (isExcute(UPLOAD_MODEL_CLUSTER)) {
            try {
                biModelService.uploadModelCluster("/", date, "dj_model_commodity_cluster.dat",
                        limit);
            } catch (Exception e) {
                throw new SQLException(e);
            } finally {
                cleanFlag(UPLOAD_MODEL_CLUSTER);
            }
        }
    }

    /**
     * 
     * 功能描述: 上传样机财务清单列表<br>
     * 〈功能详细描述〉
     * 
     * @throws SQLException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void uploadModelFinance(String date, Integer limit) throws SQLException {
        if (isExcute(UPLOAD_MODEL_FINANCE)) {
            try {
                biModelService.uploadSaleModelList("/", date, "dj_model_finance_list.dat", limit);
            } catch (Exception e) {
                throw new SQLException(e);
            } finally {
                cleanFlag(UPLOAD_MODEL_FINANCE);
            }
        }
    }

    /**
     * 
     * 功能描述:读取未维护簇商品数据<br>
     * 〈功能详细描述〉
     * 
     * @throws IOException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void downloadModelNoCluster(String date, boolean isMuti) throws IOException {
        if (isExcute(DOWNLOAD_MODEL_NOCLUSTER)) {
            try {
                biModelService.downloadNoClusterModel("/", date,
                        "dj28_01_tmp_dianjia_model_outof_cluster.dat", isMuti);
                modelManageDaoService.deleteNoClusterCommByTime(DateUtils.getDateStrByFormat(
                        new Date(), DATE_FORMAT));
            } catch (Exception e) {
                throw new IOException(e);
            } finally {
                cleanFlag(DOWNLOAD_MODEL_NOCLUSTER);
            }
        }
    }

    /**
     * 
     * 功能描述: 读取财务异常清单数据<br>
     * 〈功能详细描述〉
     * 
     * @throws IOException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void downloadSaleModelExpt(String date, boolean isMuti) throws IOException {
        if (isExcute(DOWNLOAD_SALE_MODEL_EXPT)) {
            try {
                biModelService.downloadSaleModelExpt("/", date,
                        "dj28_02_tmp_dianjia_model_notagree_finance.dat", isMuti);
                modelManageDaoService.deleteModelSaleExptByTime(DateUtils.getDateStrByFormat(
                        new Date(), DATE_FORMAT));
            } catch (IOException e) {
                throw new IOException(e);
            } finally {
                cleanFlag(DOWNLOAD_SALE_MODEL_EXPT);
            }
        }
    }

    /**
     * 
     * 功能描述: 读取样机有效性数据<br>
     * 〈功能详细描述〉
     * 
     * @throws IOException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void downloadModelValidity(String date, boolean isMuti) throws IOException {
        if (isExcute(DOWNLOAD_MODEL_VALIDITY)) {
            try {
                biModelService.downloadModelValidity("/", date,
                        "dj28_03_tmp_dianjia_model_sale_statistics_full.dat", isMuti);
            } catch (IOException e) {
                throw new  IOException(e);
            } finally {
                cleanFlag(DOWNLOAD_MODEL_VALIDITY);
            }
        }
    }
    /**
     * 
     * 功能描述: 样机任务开始定时任务<br>
     * 〈功能详细描述〉
     * 
     * @throws IOException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void modelTaskStartJob() {
        String nowDate = DateUtils.getDateStrByFormat(new Date(), DATE_FORMAT);
        List<Long> runingTaskId = modelManageDaoService.queryTaskIdByTime(nowDate, 1);
        if (CollectionUtils.isNotEmpty(runingTaskId)) {
            // 更新已到开始时间的任务状态为进行时
            modelManageDaoService.updateTaskStatusByTaskId(runingTaskId,
                    ModelConstant.TASK_RUN_STATUS_ING);
        }
    }
    /**
     * 
     * 功能描述: 样机任务结束定时任务<br>
     * 〈功能详细描述〉
     * 
     * @throws IOException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public void modelTaskEndJob(){
        String nowDate = DateUtils.getDateStrByFormat(new Date(), DATE_FORMAT);
        Integer pageLimit = Integer.valueOf(SCMConfigUtil.getConfig(
                ConfigConstants.MODEL_DEAL_LIMIT, ConfigConstants.DEFAULT_MODEL_DEAL_LIMIT));
        List<Long> endTaskId = modelManageDaoService.queryTaskIdByTime(nowDate, 2);
        if (CollectionUtils.isNotEmpty(endTaskId)) {
            // 更新已到结束时间的任务状态为已结束
            modelManageDaoService.updateTaskStatusByTaskId(endTaskId,
                    ModelConstant.TASK_RUN_STATUS_END);
            for (Long taskId : endTaskId) {
                // 根据任务Id查询任务分配表
                int count = modelManageDaoService.queryAssignTaskCount(taskId);
                if (count > 0) {
                    int pages = (count - 1) / pageLimit + 1;
                    // 分页更新任务分配表中的任务状态
                    for (int i = 0; i < pages; i++) {
                        List<Map<String, Object>> list = modelManageDaoService.queryAssignTaskById(
                                taskId, i * pageLimit, pageLimit);
                        if (CollectionUtils.isNotEmpty(list)) {
                            modelManageDaoService.batchUpdateAssignTaskStatus(list
                                    .toArray(new HashMap[list.size()]));
                        }
                    }
                }
            }
        }
    }
    /**
     * 
     * 功能描述: 创建任务分配数据<br>
     * 〈功能详细描述〉
     * 
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public void createAssignTask(Long taskId) throws SQLException {
        if (!isExcute(ASSIGN_TASK)) {
            return;
        }
        try {
            Integer pageLimit = Integer.valueOf(SCMConfigUtil.getConfig(
                    ConfigConstants.MODEL_DEAL_LIMIT, ConfigConstants.DEFAULT_MODEL_DEAL_LIMIT));
            //查询待分配任务
            List<TaskInfoPart> tasks = modelManageDaoService.queryTaskIdByStatus(
                    ModelConstant.TASK_RUN_STATUS_ING, ModelConstant.TASK_CREATE_STATUS_N, taskId);
            if (CollectionUtils.isNotEmpty(tasks)) {
                List<Map<String, Object>> insertList = new ArrayList<Map<String, Object>>();
                for (TaskInfoPart task : tasks) {
                    List<ModelTaskStoreBean> storeList = modelManageDaoService
                            .queryTaskStoreList(task.getTaskId());
                    List<BrandBean> brandList = modelManageDaoService.queryTaskBrandByTaskId(task
                            .getTaskId());
                    for (ModelTaskStoreBean store : storeList) {
                        List<String> storeBrandCodes = modelManageDaoService
                                .queryStoreBrandCode(store.getStoreCode());
                        for (BrandBean brand : brandList) {
                            // 判断该门店下是否有此品牌
                            if (storeBrandCodes.contains(brand.getBrandCode())) {
                                Map<String, Object> insertMap = new HashMap<String, Object>();
                                insertMap.put("taskId", task.getTaskId());
                                insertMap.put("taskStatus", ModelConstant.TASK_RUN_STATUS_ING);
                                insertMap.put("taskType", task.getTaskType());
                                insertMap.put("disCode", store.getDisCode());
                                insertMap.put("disName", store.getDisName());
                                insertMap.put("orgCode", store.getOrgCode());
                                insertMap.put("orgName", store.getOrgName());
                                insertMap.put("storeCode", store.getStoreCode());
                                insertMap.put("storeName", store.getStoreName());
                                insertMap.put("cateCode", brand.getCategoryCode());
                                insertMap.put("cateName", brand.getCategoryName());
                                insertMap.put("branch4code", brand.getBrand4code());
                                insertMap.put("branch9code", brand.getBrandCode());
                                insertMap.put("branchName", brand.getBrandName());
                                insertMap.put("storageCode", task.getStorageCode());
                                insertList.add(insertMap);
                                if (insertList.size() >= pageLimit) {
                                    modelManageDaoService.batchInsertTaskAssign(insertList
                                            .toArray(new HashMap[insertList.size()]));
                                    insertList = new ArrayList<Map<String, Object>>();
                                }
                            }
                        }
                    }
                    // 扫尾处理
                    if (insertList.size() > 0) {
                        modelManageDaoService.batchInsertTaskAssign(insertList
                                .toArray(new HashMap[insertList.size()]));
                    }
                    ModelTaskMain updateTask = new ModelTaskMain();
                    updateTask.setCreateStatus(ModelConstant.TASK_CREATE_STATUS_Y);
                    modelManageDaoService.updateTaskMainByTaskId(updateTask, task.getTaskId());
                }
            }
        } catch (Exception e) {
            throw new SQLException(e);
        } finally {
            cleanFlag(ASSIGN_TASK);
        }

    }

    /**
     * 
     * 功能描述: 读取财务样机增量数据<br>
     * 〈功能详细描述〉
     * 
     * @param Date
     * @throws IOException
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void downloadSaleModel(String date,Integer isInit) throws IOException {
        if (isExcute(DOWNLOAD_SALE_MODEL)) {
            try {
                if (StringUtils.isBlank(date)) {
                    Calendar c = Calendar.getInstance();
                    c.add(Calendar.DATE, -1);
                    date = DateUtils.getDateStrByFormat(c.getTime(), DATE_FORMAT_YYYYMMDD);
                }
                if(isInit != null && isInit == 1){
                    biModelService.downloadSaleModelInit(FTP_MODEL_FINANCE_INIT_PATH, date);
                }else{
                    biModelService.downloadSaleModel(FTP_MODEL_FINANCE_PATH, date);
                }
            } catch (IOException e) {
                throw new IOException(e);
            } finally {
                cleanFlag(DOWNLOAD_SALE_MODEL);
            }
        }
    }
    /**
     * 
     * 功能描述: 删除清单中已删除的品牌对应的品类品牌表中的品牌数据<br>
     * 〈功能详细描述〉
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void deleteStoreBrand(String store){
        List<String> storeCodeList = new ArrayList<String>();
        if(StringUtils.isNotBlank(store)){
            storeCodeList.add(store);
        }else{
            storeCodeList = modelManageDaoService.queryCateBrandStoreList();
        }
        if(CollectionUtils.isNotEmpty(storeCodeList)){
            for(String storeCode : storeCodeList){
                List<String> cateBrandList = modelManageDaoService.queryCateBrandByStoreCode(storeCode);
                List<String> modelBrandList = modelManageDaoService.queryBrandByStoreCode(storeCode);
                cateBrandList.removeAll(modelBrandList);
                if(CollectionUtils.isNotEmpty(cateBrandList)){
                    modelManageDaoService.deleteStoreBrand(storeCode, cateBrandList);
                }
            }
            
        }
        //清空所有品牌品类缓存
        redisClient.del(CacheKeyConstants.ALL_CATE_BRAND);
    }
    
    public void  exportCsvModelAll(Boolean op) throws IOException{
        biModelService.exportCsvModelAll(op);
    }
}
